package com.share.example.bcs.server.server.protocol;

import com.share.example.bcs.common.protocol.tcp.MsgBodyEncoder;
import com.share.example.bcs.server.server.protocol.http.HttpServerHandler;
import com.share.example.bcs.common.protocol.tcp.MsgBodyDecoder;
import com.share.example.bcs.server.server.protocol.tcp.TcpServerHandler;
import com.share.example.bcs.server.server.protocol.websocket.WebSocketServerHandler;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.List;


/**
 * 协议选择器，支持动态协议HTTP WEBSOCKET TCP私有协议
 */
@Slf4j
public class ProtocolDispatcher extends ByteToMessageDecoder {

    /*请求头GET,POST,PUT,HEAD,OPTIONS,PATCH,DELETE,TRACE,CONNECT*/
    String HTTP_PREFIX = "GET,POS,PUT,HEA,OPT,PAT,DEL,TRA,CON";
    private static final int HTTP_CHECK_LENGTH = 3;

    //根据协议去适配协议
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        ChannelPipeline pipeline = ctx.pipeline();
        int length = in.readableBytes();
        if (length < HTTP_CHECK_LENGTH) {
            log.info("收到一个请求,请求数据头异常!");
            return;
        }

        //1.读取前几个字节
        byte[] content = new byte[HTTP_CHECK_LENGTH];
        ByteBuf byteBuf = in.readBytes(content);
        String protocolStartChar = new String(content, CharsetUtil.UTF_8);
        log.debug("协议开始字符标志={}", protocolStartChar);

        //2.回退指针--必须否则后面不完整
        byteBuf.resetReaderIndex();

        //3.协议判断
        if (HTTP_PREFIX.contains(protocolStartChar)) {
            //再次读取数据
            byte[] tmpByte = new byte[32];
            ByteBuf tmpByteBuf = in.readBytes(tmpByte);
            String tmpContent = new String(tmpByte, CharsetUtil.UTF_8);

            //回退指针--必须否则后面不完整
            tmpByteBuf.resetReaderIndex();

            if (tmpContent.contains("websocket")) {
                pipeline.addLast(new HttpServerCodec());
                pipeline.addLast(new HttpObjectAggregator(8192));
//                pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PREFIX));
                pipeline.addLast(new WebSocketServerHandler());
            } else {
                pipeline.addLast(new HttpRequestDecoder());
                pipeline.addLast(new HttpObjectAggregator(65536));
                pipeline.addLast(new HttpResponseEncoder());
                pipeline.addLast(new HttpServerHandler());//我们编写的
            }
        } else {
            pipeline.addLast(new MsgBodyDecoder());
            pipeline.addLast(new TcpServerHandler());
            pipeline.addLast(new MsgBodyEncoder());
        }

        //5.移除当前的这个解码器,切记是最后移除
        pipeline.remove(this);
    }
}
